package com.solr.web.controller.search;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.solr.web.model.base.ResultModel;
import com.solr.web.model.vo.search.AreaVo;
import com.solr.web.model.vo.search.KeywordVo;
import com.solr.web.model.vo.search.PublishtimeVo;
import com.solr.web.model.vo.search.SearchVo;
import com.solr.web.model.vo.search.Search_SINFOVo;
import com.solr.web.service.search.SearchService;

@RequestMapping("/search")
@Controller
public class SearchController {
	
	@Autowired
	SearchService searchService;

	@Autowired
	private SearchService service;
	
	@Autowired
	private SolrServer solrServer;
	
	/**
	 * 进入页面
	 * @return
	 */
    @RequestMapping(value = "/view", method = RequestMethod.GET)
    public String view() {
        return "search";
    }
	
    /**
	 * 搜索
	 * @return
	 */
	@RequestMapping("/search")
	@ResponseBody
	public Map<String, Object> search(String q, @RequestParam(defaultValue = "1") Integer page, String fq,String fq_rate,Map<String, Object> model){
		ResultModel result = new ResultModel();
		Map<String, Object> map =null;
			try {
				//解决get方式的中文乱码
				/*if (StringUtils.isNotEmpty(q)) {
				q = new String(q.getBytes("ISO-8859-1"),"utf-8");
				}*/
				
				//首字母搜索、股票代码搜索
				if ("".equals(q)) {
					map=service.search(q, page, fq,fq_rate);
				}else{
					for (char c : q.toCharArray()) {  
			            if (!isChinese(c)){
			            	if (q.length()==9) {
			            		String S_INFO_NAME = searchService.getNameFromWindCode(q).getS_INFO_NAME();
			            		if (S_INFO_NAME.contains("(")) {
			            			S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
								}
			            		map=service.search(S_INFO_NAME, page, fq,fq_rate);
			            		
							}else if(q.length()==6){
								String S_INFO_NAME = searchService.getNameFromCode(q).getS_INFO_NAME();
								if (S_INFO_NAME.contains("(")) {
			            			S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
								}
			            		map=service.search(S_INFO_NAME, page, fq,fq_rate);
			            		
			            	//判断字符串是否都是字母
							}else if(q.matches("[a-zA-Z]+")){
								if (searchService.getNameFromPinYin(q) ==null ) {
									map=service.search(q, page, fq,fq_rate);
									
								}else {
									
									String S_INFO_NAME = searchService.getNameFromPinYin(q).getS_INFO_NAME();
									if (S_INFO_NAME.contains("(")) {
										S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
									}
									map=service.search(S_INFO_NAME, page, fq,fq_rate);
								}
			            		
							}else{
								map=service.search(q, page, fq,fq_rate);
								
							}
			            }else {
			            	// 有一个中文字符就返回
			            	map=service.search(q, page, fq,fq_rate);
						}
			        }
				}
				
				
				//将数据放入request域
				model.put("query", q);
				model.put("page", page);
				model.put("totalPages", map.get("totalPages"));
				model.put("searchVoList", map.get("searchVoList"));
				model.put("totalRecords", map.get("totalRecords"));
				
			} catch (Exception e) {
				e.printStackTrace();
		}
			return map;
		
	}
	

	/**
	 * 查询索引日期下的全部 “title”
	 * @param q
	 * @param date
	 * @return
	 */
	@RequestMapping("/searchCountWhere")
	@ResponseBody
	public Map<String, Object> searchCountWhere(String q,String fq,String date){
		int i=0;
		Map<String, Object> map =null;
		try {
			
		SolrDocumentList results = solrPublic(q, fq);
		
		long totalRecords = results.getNumFound();
		System.out.println(totalRecords);
		
		map = new HashMap<>();

		List<SearchVo> searchVoList = new ArrayList<>();
		SearchVo searchVo;
		
		for (SolrDocument solrDocument : results) {
			searchVo = new SearchVo();
			String string2 = solrDocument.get("publishtime").toString();
			//System.out.println("string2"+string2);
			//if(string2.contains("2016-09-09")){
			if(string2.indexOf(date)!=-1){
				i++;
				String keyword = solrDocument.get("keyword").toString();
				String title = solrDocument.get("title").toString();
				String href = solrDocument.get("href").toString();
				//System.out.println(title);
				//map.put(i+"",title);
				searchVo.setKeyword(keyword);
				searchVo.setTitle(title);
				searchVo.setHref(href);
				searchVoList.add(searchVo);
			}
		}
		
		map.put("count", i);
		map.put("searchVoList", searchVoList);
		
	    //System.out.println(i);
	    
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	/**
	 * 统计：当前索引下城市/公司 按时间排序(((加入首字母搜索、股票代码搜索)
	 * @param q
	 * @param fq
	 * @return
	 */
	@RequestMapping("/orderByTime")
	@ResponseBody
	public Map<String, Object> orderByTime(String q,String fq, Integer page) throws Exception {
		Map<String, Object> map =null;
		
		//首字母搜索、股票代码搜索
			for (char c : q.toCharArray()) { 
	            if (!isChinese(c)){
	            	if (q.length()==9) {
	            		String S_INFO_NAME = searchService.getNameFromWindCode(q).getS_INFO_NAME();
	            		if (S_INFO_NAME.contains("(")) {
	            			S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
						}
	            		map = orderByTime_(S_INFO_NAME, fq, page);
	            		
					}else if(q.length()==6){
						String S_INFO_NAME = searchService.getNameFromCode(q).getS_INFO_NAME();
						if (S_INFO_NAME.contains("(")) {
	            			S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
						}
						map = orderByTime_(S_INFO_NAME, fq, page);
	            		
	            	//判断字符串是否都是字母
					}else if(q.matches("[a-zA-Z]+")){
						if (searchService.getNameFromPinYin(q) ==null ) {
							map = orderByTime_(q, fq, page);
							
						}else {
							String S_INFO_NAME = searchService.getNameFromPinYin(q).getS_INFO_NAME();
							if (S_INFO_NAME.contains("(")) {
		            			S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
							}
							map = orderByTime_(S_INFO_NAME, fq, page);
						}
					}else{
						map = orderByTime_(q, fq, page);
						
					}
	            }else {
	            	// 有一个中文字符就返回
	            	map = orderByTime_(q, fq, page);
				}
	        }
		
		return map;
		
	}
	
	/**
	 * 统计：当前索引下城市/公司 按时间排序
	 * @param q
	 * @param fq
	 * @return
	 */
	public Map<String, Object> orderByTime_(String q,String fq, Integer page) throws Exception {
		//String fq ="servicetype:(0 2)";
		Map<String, Object> resultMap =null;
		try {
			//查询对象
			SolrQuery query = new SolrQuery();
			
			StringBuffer sb = new StringBuffer();
			//设置查询关键字
			if (StringUtils.isNotEmpty(q)) {
				if (q.indexOf(" ")!=-1) {
					String[] strings = q.split(" ");
					for (int i = 0; i < strings.length; i++) {
						q='"'+strings[i]+'"';
						sb.append(q+" ");
					}
					query.setQuery(sb.toString());
				}else {
					query.setQuery('"'+q+'"');
				}
			}else {
				query.setQuery("*:*");
			}
			
			//设置分页
			if (page==null) {
				page=1;
			}
			
			query.setStart((page - 1)*100);
			query.setRows(100);
			
			//设置默认域
			query.set("df", "title");
			query.set("qt", "/select");		
			query.set("wt", "json");
			query.set("sort", "publishtime desc");
			query.setFilterQueries(fq);
			//query.setRows((int) solrServer.query(query).getResults().getNumFound());
			
			//搜索
			QueryResponse response = solrServer.query(query);
			SolrDocumentList results = response.getResults();
			
			//索引结果总数
			Integer total = (int) results.getNumFound();
			
			resultMap = new LinkedHashMap<String,Object>();
			
			//放入set去重
			Set<String> set = new LinkedHashSet<String>();
			
			//地点排序
			Map<String, Object> areaMap = new LinkedHashMap<String,Object>();
			String str1="area";
			for (SolrDocument solrDocument : results) {
				String string = solrDocument.get(str1).toString();
				if (string != null && !"".equals(string)) {
					set.add(string);
				}
			}	
			
			List<AreaVo> areaList = new LinkedList<>();
			AreaVo areaVo;
			for (String str : set) {
				areaVo = new AreaVo();
				areaVo.setArea(str);
				areaList.add(areaVo);
			}
			//areaMap.put("areaGroup", set.size());
			areaMap.put(str1+"List", areaList);
			
			
			//公司排序
			set.clear();
			Map<String, Object> keywordMap = new LinkedHashMap<String,Object>();
			String str2="keyword";
			for (SolrDocument solrDocument : results) {
				String string = solrDocument.get(str2).toString();
				if (string != null && !"".equals(string)) {
					set.add(string);
				}
			}	
			
			List<KeywordVo> keywordList = new LinkedList<>();
			KeywordVo keywordVo;
			for (String str : set) {
				keywordVo = new KeywordVo();
				keywordVo.setCompany(str);
				keywordList.add(keywordVo);
			}
			
			//keywordMap.put("keywordGroup", set.size());
			keywordMap.put(str2+"List", keywordList);

			
			resultMap.put("total", total);
			resultMap.put("area", areaMap);
			resultMap.put("keyword", keywordMap);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
		
	}
	
	/**
	 * 统计：当前索引下城市地点出现频率排序/公司出现频率排序
	 * @param q
	 * @param fq
	 * @return
	 */
	@RequestMapping("/count")
	@ResponseBody
	public Map<String, Object> count(String q,String fq){
		SolrDocumentList results = solrPublic(q,fq);
		
		Map<String, Object> map =new HashMap<>();
		
		try {
			Map<String, Object> areaSearchMap = searchArea(q, fq, "area",results);
			Map<String, Object> kwSearchMap = searchKeyword(q, fq, "keyword",results);
			
			map.put("area", areaSearchMap);
			map.put("keyword", kwSearchMap);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	/**
	 * 当前索引下公司出现频率 并排序
	 * @param q
	 * @param fq
	 * @param str
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	public Map<String, Object> searchKeyword(String q,String fq,String str,SolrDocumentList results) throws Exception {
		//String fq ="servicetype:(0 2)";
		Map<String, Object> map =null;
		Map<String,Object> resultMap = null;
		try {
			
		//索引结果总数
		Integer total = (int) results.getNumFound();

		map = new HashMap<String,Object>();
		
		//有多少个统计组
		int count =0;
		
		//计数
		int i=0;
		
		//统计当前索引下城市地点出现频率 并排序
		//放入set去重
		Set<String> hs = new HashSet<String>();
		for (SolrDocument solrDocument : results) {
			String string = solrDocument.get(str).toString();
			if (string != null && !"".equals(string)) {
				hs.add(string);
			}
		}
		List<String> list = new ArrayList<String>(hs);
		for (String string : list) {
			i=0;
			count++;
			for (int k = 0; k < results.size(); k++) {
					String string2 = results.get(k).get(str).toString();
					if(string2.equals(string)){
						i++;
					}
			}
			//System.out.println(string+"-----------------------"+i);
			map.put(string,i);
		}
		
		map = sortMap(map);
		
		List<KeywordVo> objectlist = new LinkedList<KeywordVo>();
		KeywordVo vo;
		Iterator it = map.entrySet().iterator();  
	    while(it.hasNext()){  
	    	vo = new KeywordVo();
	        Map.Entry<String, Integer> entry = (Map.Entry) it.next();  
	        vo.setCompany(entry.getKey());
	        vo.setCount(entry.getValue());
	        objectlist.add(vo);
	        //System.out.println(entry.getKey() + ":" + entry.getValue());  
	    }
		
		//System.out.println("count+++++++++"+count);
	    resultMap = new HashMap<String,Object>();
	    
	    resultMap.put("total", total);
	    resultMap.put("group", count);
	    resultMap.put(str+"List", objectlist);
		
		//System.out.println(total);
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
		
	}
	
	
	/**
	 * 当前索引下地区出现频率并排序
	 * @param q
	 * @param fq
	 * @param str
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	public Map<String, Object> searchArea(String q,String fq,String str,SolrDocumentList results) throws Exception {
		//String fq ="servicetype:(0 2)";
		Map<String, Object> map =null;
		Map<String,Object> resultMap = null;
		try {
			
			//索引结果总数
			Integer total = (int) results.getNumFound();
			
			map = new HashMap<String,Object>();
			
			//有多少个统计组
			int count =0;
			
			//计数
			int i=0;
			
			//统计当前索引下城市地点出现频率 并排序
			//放入set去重
			Set<String> hs = new HashSet<String>();
			for (SolrDocument solrDocument : results) {
				String string = solrDocument.get(str).toString();
				if (string != null && !"".equals(string)) {
					hs.add(string);
				}
			}
			List<String> list = new ArrayList<String>(hs);
			for (String string : list) {
				i=0;
				count++;
				for (int k = 0; k < results.size(); k++) {
					String string2 = results.get(k).get(str).toString();
					if(string2.equals(string)){
						i++;
					}
				}
				//System.out.println(string+"-----------------------"+i);
				map.put(string,i);
			}
			
			map = sortMap(map);
			
			List<AreaVo> objectlist = new LinkedList<AreaVo>();
			AreaVo vo;
			Iterator it = map.entrySet().iterator();  
			while(it.hasNext()){  
				vo = new AreaVo();
				Map.Entry<String, Integer> entry = (Map.Entry) it.next();  
				vo.setArea(entry.getKey());
				vo.setCount(entry.getValue());
				objectlist.add(vo);
				//System.out.println(entry.getKey() + ":" + entry.getValue());  
			}
			
			//System.out.println("count+++++++++"+count);
			resultMap = new HashMap<String,Object>();
			
			resultMap.put("total", total);
			resultMap.put("group", count);
			resultMap.put(str+"List", objectlist);
			
			//System.out.println(total);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
		
	}
	
	/**
	 * solr搜索，返回结果集(((加入首字母搜索、股票代码搜索)
	 * @param q
	 * @param fq
	 * @return
	 */
	public SolrDocumentList solrPublic(String q,String fq){
		SolrDocumentList results = null;
		//首字母搜索、股票代码搜索
		for (char c : q.toCharArray()) { 
            if (!isChinese(c)){
            	if (q.length()==9) {
            		String S_INFO_NAME = searchService.getNameFromWindCode(q).getS_INFO_NAME();
            		if (S_INFO_NAME.contains("(")) {
            			S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
					}
            		results = solrPublic_(S_INFO_NAME, fq);
            		
				}else if(q.length()==6){
					String S_INFO_NAME = searchService.getNameFromCode(q).getS_INFO_NAME();
					if (S_INFO_NAME.contains("(")) {
            			S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
					}
					results = solrPublic_(S_INFO_NAME, fq);
            		
            	//判断字符串是否都是字母
				}else if(q.matches("[a-zA-Z]+")){
					if (searchService.getNameFromPinYin(q) ==null ) {
						results = solrPublic_(q, fq);
						
					}else {
						String S_INFO_NAME = searchService.getNameFromPinYin(q).getS_INFO_NAME();
						if (S_INFO_NAME.contains("(")) {
	            			S_INFO_NAME = S_INFO_NAME.substring(0, S_INFO_NAME.indexOf("("));
						}
						results = solrPublic_(S_INFO_NAME, fq);
					}
				}else{
					results = solrPublic_(q, fq);
					
				}
            }else {
            	// 有一个中文字符就返回
            	results = solrPublic_(q, fq);
			}
        }
		
		return results;
		
	}
	
	/**
	 * solr搜索，返回结果集
	 * @param q
	 * @param fq
	 * @return
	 */
	public SolrDocumentList solrPublic_(String q,String fq){
		SolrDocumentList results = null;
		try {
			//查询对象
			SolrQuery query = new SolrQuery();

			StringBuffer sb = new StringBuffer();
			//设置查询关键字
			if (StringUtils.isNotEmpty(q)) {
				if (q.indexOf(" ")!=-1) {
					String[] strings = q.split(" ");
					for (int i = 0; i < strings.length; i++) {
						q='"'+strings[i]+'"';
						sb.append(q+" ");
					}
					query.setQuery(sb.toString());
				}else {
					query.setQuery('"'+q+'"');
				}
			}else {
				query.setQuery("*:*");
			}
			
			//设置默认域
			query.set("df", "title");
			query.set("qt", "/select");		
			query.set("wt", "json");
			query.setFilterQueries(fq);
			query.setRows((int) solrServer.query(query).getResults().getNumFound());
			//搜索
			QueryResponse response = solrServer.query(query);
			results = response.getResults();
				
		} catch (Exception e) {
			e.printStackTrace();
		}
		return results;
	}
	
	/**
	 * 排序
	 * @param map
	 * @return
	 */
	public static Map sortMap(Map map) {  
	    List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());  
	    Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {  

	        @Override  
	        public int compare(Entry<java.lang.String, Integer> arg0,  
	                Entry<java.lang.String, Integer> arg1) {  
	            return arg1.getValue() - arg0.getValue();  
	        }  
	    });  
	    Map newMap = new LinkedHashMap();  
	    for (int i = 0; i < list.size(); i++) {  
	        newMap.put(list.get(i).getKey(), list.get(i).getValue());  
	    }  
	    return newMap;  
	}
	
	/**
	 * 按时间排序，统计每天信息数量
	 * @param q
	 * @return
	 */
	@RequestMapping("/searchCount")
	@ResponseBody
	public Map<String, Object> searchCount(String q,String fq){
		
		Map<String, Object> map =null;
		try {
			
		SolrDocumentList results = solrPublic(q, fq);
		
		//索引结果总数
		long totalRecords = results.getNumFound();
		
		map = new LinkedHashMap<>();
		//有多少个统计组
		int count =0;
		//计数
		int i=0;
		//放入set去重
		Set<String> hs = new HashSet<String>();
		for (SolrDocument solrDocument : results) {
			if (solrDocument.get("publishtime") != null && solrDocument.get("publishtime").toString().length() > 0) {
				String publishtime = solrDocument.get("publishtime").toString();
	//			String substring = publishtime.substring(0, 10);
				String substring = publishtime.split(" ")[0];
				hs.add(substring);
			}
		}
		
		//根据时间排序
		List<String> list = new ArrayList<String>(hs);
		Collections.sort(list);
		
		List<PublishtimeVo> lkList = new LinkedList<PublishtimeVo>();
		PublishtimeVo vo;
		for (String publishtime : list) {
			vo = new PublishtimeVo();
			i=0;
			count++;
			for (int k = 0; k < results.size(); k++) {
				if (results.get(k).get("publishtime") != null && results.get(k).get("publishtime").toString().length() > 0) {
					String publishtime2 = results.get(k).get("publishtime").toString();
					if(publishtime2.contains(publishtime)){
						i++;
					}
				}
			}
			//map.put(publishtime,i);
			//System.out.println(publishtime+"-----------------------"+i);
			vo.setTime(publishtime);
			vo.setCount(i);
			lkList.add(vo);
		}
		//System.out.println("count+++++++++"+count);
		
		map.put("totalRecords", totalRecords);
		map.put("publishtime", lkList);
		//System.out.println(totalRecords);
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	/**
	 * 提示
	 * @param q
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/suggest")
	@ResponseBody
	public SolrDocumentList suggest(String q,Model model) throws Exception {
		//ResultModel result = new ResultModel();
		
		//List<String>  wordList=new ArrayList<String>();
		
		//解决get方式的中文乱码
		/*if (StringUtils.isNotEmpty(q)) {
		q = new String(q.getBytes("ISO-8859-1"),"utf-8");
		}*/
		
		//查询对象
		SolrQuery query = new SolrQuery();
		
		//设置查询关键字
		query.set("q","title:"+q);

		query.set("qt", "/select");		
		//设置默认域
		query.set("df", "title");
		//query.set("rows", "100");
		query.set("wt", "json");
		
		//搜索
		QueryResponse response = solrServer.query(query);
		SolrDocumentList results = response.getResults();
		
		//for (SolrDocument solrDocument : results) {
			//String str = (String) solrDocument.get("title");
			//System.out.println(str);
			//wordList.add(str);
		//}
		//model.addAttribute("wordList",wordList);
		return results;
		
	}
	
	
	
	/**
	 * 判断一个字符是否是中文
	 * @param c
	 * @return
	 */
	public static boolean isChinese(char c) {  
        return c >= 0x4E00 &&  c <= 0x9FA5;// 根据字节码判断  
    }  
    
	/**
	 * 判断一个字符串是否含有中文
	 * @param str
	 * @return
	 */
    public static boolean isChinese(String str) {  
        if (str == null) return false;  
        for (char c : str.toCharArray()) {  
            if (isChinese(c)) return true;// 有一个中文字符就返回  
        }  
        return false;  
    } 
}